﻿using Common.Enums;
using Common.Exceptions;
using Common.Models;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using System.Linq;
using Wallpaper.Data.Context;
using Wallpaper.Data.Dal;
using Wallpaper.Data.IDal;
using Wallpaper.Models.DTOs.Requests.Wallpaper;
using Wallpaper.Models.DTOs.Responses.message;
using Wallpaper.Models.Entities;
using Wallpaper.Services.IService;
using Wallpaper.Services.Socket;

namespace Wallpaper.Services.Service
{
    public class MessageService : IMessageService
    {
        readonly IMessageDal _messageDal;
        readonly WallpaperDbContext _dbContext;
        readonly IUserMessageDal _userMessageDal;


        public MessageService(IMessageDal messageDal, WallpaperDbContext dbContext, IUserMessageDal userMessageDal)
        {
            _messageDal = messageDal;
            _dbContext = dbContext;
            _userMessageDal = userMessageDal;
        }

        /// <summary>
        /// 获取审核壁纸消息分页
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<PagedResult<MessageResponse>> GetReviewWallpapersMessagesAsync(PageRequest pageRequest)
        {
            var query = _messageDal.GetQueryable()
                .Where(m => m.MessageType == MessageType.ReviewNotification && m.RelatedType == RelatedType.Wallpaper)
                .OrderByDescending(w => w.CreatedAt);

            int count = await query.CountAsync();

            var items = await query
                .Include(m => m.userMessages) // 正确的大小写
                .Skip((pageRequest.Page - 1) * pageRequest.PageSize)
                .Take(pageRequest.PageSize)
                .ToListAsync(); //To

            var responseItems = items.Select(m => new MessageResponse
            {
                Id = m.Id,
                Content = m.Content,
                MessageType = m.MessageType == MessageType.ReviewNotification ? "审核通知" : "系统通知",
                CreateTime = m.CreatedAt,
                IsRead = m.userMessages.FirstOrDefault()?.IsRead ?? false 
            }).ToList(); 

            return new PagedResult<MessageResponse>
            {
                Items = responseItems,
                TotalCount = count,
                Page = pageRequest.Page,
                PageSize = pageRequest.PageSize
            };
        }

        /// <summary>
        /// 获取个人审核壁纸消息
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="pageRequest"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<PagedResult<MessageResponse>> GetUserReviewWallpapersMessagesAsync(string userId, PageRequest pageRequest)
        {
            if (userId == null)
            {
                throw new ArgumentNullException(nameof(userId), "用户ID不能为空");
            }

            // 使用 Join 进行一次性查询，更高效
            var query = from m in _messageDal.GetQueryable()
                        join um in _userMessageDal.GetQueryable()
                        on m.Id equals um.MessageId
                        where um.UserId == userId &&
                              m.MessageType == MessageType.ReviewNotification &&
                              m.RelatedType == RelatedType.Wallpaper
                        orderby m.CreatedAt descending
                        select new { Message = m, UserMessage = um };

            int count = await query.CountAsync();

            var items = await query
                .Skip((pageRequest.Page - 1) * pageRequest.PageSize)
                .Take(pageRequest.PageSize)
                .ToListAsync();

            var responseItems = items.Select(x => new MessageResponse
            {
                Id = x.Message.Id,
                Content = x.Message.Content,
                MessageType = x.Message.MessageType == MessageType.ReviewNotification ? "审核通知" : "系统通知",
                CreateTime = x.Message.CreatedAt,
                IsRead = x.UserMessage.IsRead // 直接从 Join 结果中获取
            }).ToList();

            return new PagedResult<MessageResponse>
            {
                Items = responseItems,
                TotalCount = count,
                Page = pageRequest.Page,
                PageSize = pageRequest.PageSize
            };
        }


        /// <summary>
        /// 标记为已读
        /// </summary>
        /// <param name="userMessageId"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task MarkAsReadAsync(string userMessageId)
        {
            // 使用ExecuteUpdateAsync直接在数据库执行UPDATE语句
            // 生成的SQL类似：UPDATE UserMessages SET IsRead = 1 WHERE Id = @userMessageId
            var result = await _dbContext.UserMessages
                .Where(um => um.Id == userMessageId)  // 筛选指定ID的用户消息
                .ExecuteUpdateAsync(setters => setters
                .SetProperty(um => um.IsRead, true)
                .SetProperty(um => um.ReadAt, DateTime.Now)  // 手动设置阅读时间// 设置IsRead字段为true（已读）
                );

            if (result == 0)
            {
                throw new BusinessException("数据不存在或服务器错误", 404);
            }
        }

        /// <summary>
        /// 发送审核通知并存储到数据库
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="wallpaperId"></param>
        /// <param name="wallpaperTitle"></param>
        /// <param name="isApproved"></param>
        /// <param name="reason"></param>
        /// <returns></returns>
        public async Task SendReviewNotificationAsync(string userId, string wallpaperId, string wallpaperTitle, WallpaperReviewStatus reviewStatus, string reason = null)
        {
            // 使用 EF Core 的事务
            using var transaction = await _dbContext.Database.BeginTransactionAsync();

            try
            {
                // 1. 创建主消息记录
                var message = new Message
                {
                    Id = Guid.NewGuid().ToString(),
                    MessageType = MessageType.ReviewNotification,
                    // 只处理 Approved 和 Rejected 状态
                    Content = reviewStatus switch
                    {
                        WallpaperReviewStatus.Approved => $"您的壁纸《{wallpaperTitle}》已通过审核",
                        WallpaperReviewStatus.Rejected => $"您的壁纸《{wallpaperTitle}》审核未通过" +
                            (string.IsNullOrEmpty(reason) ? "" : $"，原因：{reason}"),
                        _ => "状态未知"  // 如果状态不在 Approved 或 Rejected 里，就返回一个默认的错误消息
                    },
                    SenderId = null,
                    RelatedId = wallpaperId,
                    RelatedType = RelatedType.Wallpaper,
                    CreatedAt = DateTime.Now
                };
                
                await _messageDal.CreateEntityAsync(message);
                var jsonMessage = JsonConvert.SerializeObject(message);

                // 发送消息到指定用户
                await WebSocketService.SendMessageToUserAsync(userId, jsonMessage);
                // 2. 创建用户消息关联
                var userMessage = new UserMessage
                {
                    Id = Guid.NewGuid().ToString(),
                    MessageId = message.Id,
                    UserId = userId,
                    IsRead = false,
                    CreatedAt = DateTime.Now
                };

                await _dbContext.UserMessages.AddAsync(userMessage);

                // 3. 保存更改并提交事务
                await _dbContext.SaveChangesAsync();
                await transaction.CommitAsync();
                Console.WriteLine($"已向用户 {userId} 发送审核通知: {reason}"); // 添加日志
            }
            catch (Exception ex)
            {
                Console.WriteLine($"发送审核通知失败: {ex.Message}"); // 添加错误日志
                await transaction.RollbackAsync();
                throw; // 重新抛出异常
            }
        }

     
    }
}
